package org.fhkoeln.sgdm.sudoku.gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

import org.fhkoeln.sgdm.sudoku.logic.SudokuField;

public class SudokuPanel extends JPanel implements MouseMotionListener, MouseListener, KeyListener
{
	private static final long serialVersionUID = 0L;
	
	private int width = 40;
	private int height = 40;
	
	private Stroke stdStroke = null;
	private Stroke fatStroke = null;
	
	SudokuField curField = null;
	
	private int mouseX = 0;
	private int mouseY = 0;
	
	private static SudokuPanel instance = null;
	
	private SudokuPanel()
	{
		stdStroke = new BasicStroke(1);
		fatStroke = new BasicStroke(5);
		
		this.addMouseMotionListener(this);
		this.addMouseListener(this);
		this.addKeyListener(this);
	}
	
	public static SudokuPanel getInstance()
	{
		if(instance == null)
		{
			instance = new SudokuPanel();
		}
		return instance;
	}
	
	public void setSudokuField(SudokuField field)
	{
		curField = field;
	}
	
	public SudokuField getSudokuField()
	{
		return curField;
	}
	
	@Override
	public void paint(Graphics g)
	{
		Graphics2D g2d = (Graphics2D)g;
		
		g.setColor(Color.black);
		g.fillRect(0, 0, this.getWidth(), this.getHeight());
		
		g.setColor(Color.white);
		

		if(curField == null || curField.values == null)
			return; 
		
		Font myFont = this.getFont().deriveFont(30.0f);
		
		g.setFont(myFont);
		
		g2d.setStroke(stdStroke);
		
		for(int i = 1; i <= 10; i ++)
		{
			if(i%3 == 1)
			{
				g2d.setStroke(fatStroke);
			}
			else
			{
				g2d.setStroke(stdStroke);
			}
			
			g.drawLine(i * width, 20, i * width, 9 * height + 20);
		}
		
		for(int i = 0; i <= 9; i ++)
		{
			if(i%3 == 0)
			{
				g2d.setStroke(fatStroke);
			}
			else
			{
				g2d.setStroke(stdStroke);
			}
			g.drawLine(width, i * height + 20, 10 * width, i * height + 20);
		} 
		
		if(mouseX <= 8 && mouseY <= 8)
		{
			g.setColor(Color.green);
			g.fillRect(mouseX * 40 + 40, mouseY * 40 + 20, 40, 40);	
		}
		g.setColor(Color.white);
		for(int j = 0; j < 9; j ++)
		{
			for(int i = 0; i < 9; i ++)
			{
				if(curField.values[j][i] > 0)
				{
					if(i == mouseX && j == mouseY)
					{
						g.setColor(Color.black);
					}
					g.drawString("" + curField.values[j][i], (i+1) * width + 10, (j+1) * height + 10);
					if(i == mouseX && j == mouseY)
					{
						g.setColor(Color.white);
					}
				}
			}
		}
	}

	@Override
	public void mouseDragged(MouseEvent arg0)
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent arg0)
	{
		
	}

	@Override
	public void mouseClicked(MouseEvent arg0)
	{
		mouseX = (arg0.getX() - 40) / 40;
		mouseY = (arg0.getY() - 20) / 40;
		this.repaint();
	}

	@Override
	public void mouseEntered(MouseEvent arg0)
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0)
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0)
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0)
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyPressed(KeyEvent arg0)
	{

	}

	@Override
	public void keyReleased(KeyEvent arg0)
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent arg0)
	{
		// TODO Auto-generated method stub

	}
	
	public void putDigit(int val)
	{
		if(mouseX < 9 && mouseY < 9 &&
				mouseX >= 0 && mouseY >= 0)
		{
			curField.values[mouseY][mouseX] = val;
			curField.createFixedMap();
		}
		repaint();
	}
}
